﻿//========================================================= 
/**@file jsoncpp_extractor.h
 * @brief 使用JsonCpp库做json数据转换
 * 
 * @date 2016-05-21   11:13:58
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_JSONCPP_EXTRACTOR_H_
#define _LIBZHOUYB_JSONCPP_EXTRACTOR_H_
//--------------------------------------------------------- 
#include <json/autolink.h>
#include <json/config.h>
#include <json/features.h>
#include <json/forwards.h>
#include <json/value.h>
#include <json/reader.h>
#include <json/writer.h>

#include "../../include/Base.h"
//--------------------------------------------------------- 
namespace zhou_yb {
namespace wrapper {
namespace jsoncpp_extractor {
//--------------------------------------------------------- 
/// Json参数解析器
class JsonArgParser : public IStringArgParser, public RefObject
{
public:
    /// 将字符串转换为Json对象
    static bool ToJson(const ByteArray& sJson, Json::Value& root)
    {
        Json::Reader reader(Json::Features::strictMode());
        const char* endDoc = sJson.GetString() + sJson.GetLength();
        return reader.parse(sJson.GetString(), endDoc, root, false);
    }
    /// 将Json::Value转换为对应的字符串形式
    static string ToString(Json::Value& item)
    {
        if(item.isString())
        {
            return item.asString();
        }
        else if(item.isBool())
        {
            return ArgConvert::ToString(item.asBool());
        }
        else if(item.isDouble())
        {
            return ArgConvert::ToString(item.asDouble());
        }
        else if(item.isInt())
        {
            return ArgConvert::ToString(item.asInt());
        }
        else if(item.isUInt())
        {
            return ArgConvert::ToString(item.asUInt());
        }
        else if(item.isNull())
        {
            return "";
        }
        else if(item.isObject())
        {
            Json::FastWriter writer;
            return writer.write(item);
        }
        return item.toStyledString();
    }
    /// 将Json数组序列化到Arg中
    static size_t ArrayToARG(Json::Value& arr, const string& sKey, IStringArguments& arg)
    {
        Json::UInt count = arr.size();
        for(Json::UInt i = 0; i < count; ++i)
        {
            arg.Put(sKey, ToString(arr[i]));
        }
        return count;
    }
    /// 将Json对象数组字段拆开再序列化到Arg中
    static size_t ObjArrayToARG(Json::Value& arr, IStringArguments& arg)
    {
        Json::UInt count = arr.size();
        for(Json::UInt i = 0; i < count; ++i)
        {
            Json::Value& item = arr[i];
            Json::Value::Members keys = item.getMemberNames();
            Json::Value::Members::iterator itr;
            for(itr = keys.begin(); itr != keys.end(); ++itr)
            {
                arg.Put(*itr, ToString(item[*itr]));
            }
        }
        return count;
    }

    JsonArgParser()
    {
        IsTrimEnd = true;
    }
    /// 解析json字符串
    virtual size_t Parse(const ByteArray& str, IStringArguments& arg)
    {
        Json::Value root;
        size_t count = 0;
        if(!ToJson(str, root))
            return count;
        if(root.isArray())
        {
            count += ArrayToARG(root, "", arg);
        }
        else
        {
            Json::Value::Members argMembers = root.getMemberNames();
            Json::Value::Members::iterator itr;
            for(itr = argMembers.begin(); itr != argMembers.end(); ++itr)
            {
                Json::Value& item = root[*itr];
                if(item.isArray())
                {
                    count += ArrayToARG(item, *itr, arg);
                }
                else
                {
                    arg.Put(*itr, ToString(item));
                    ++count;
                }
            }
        }
        return count;
    }
    /// 将数据转为json字符串
    virtual size_t ToString(const IStringArguments& arg, ByteBuilder& str)
    {
        Json::FastWriter writer;
        Json::Value root;
        IStringArguments::EnumeratorType enumer = arg.GetEnumerator();
        size_t count = 0;
        while(enumer.MoveNext())
        {
            if(root.isMember(enumer.Current().Key))
            {
                Json::Value& item = root[enumer.Current().Key];
                if(item.isArray())
                {
                    item.append(enumer.Current().Value);
                    continue;
                }
                string val = item.asString();
                root.removeMember(enumer.Current().Key);

                Json::Value& newItem = root[enumer.Current().Key];
                newItem.append(val);
                newItem.append(enumer.Current().Value);
            }
            else
            {
                root[enumer.Current().Key] = enumer.Current().Value;
            }
            ++count;
        }
        if(count < 1)
            return 0;

        string jsonstr = writer.write(root);
        size_t len = jsonstr.length();
        if(IsTrimEnd)
            --len;

        str.Append(ByteArray(jsonstr.c_str(), len));
        return len;
    }
    /// 在生成Json字符串时,是否自动剔除末尾的换行符
    bool IsTrimEnd;
};
//--------------------------------------------------------- 
} // namespace jsoncpp_extractor
} // namespace wrapper
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_JSONCPP_EXTRACTOR_H_
//========================================================= 